﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;


namespace gheat
{
    /// <summary>
    /// The base directory is set in the settings.
    /// </summary>
    public class GHeat
    {
        public const int SIZE = 256; // # size of (square) tile; NB: changing this will break gmerc calls!
        public const int MAX_ZOOM = 31; // # this depends on Google API; 0 is furthest out as of recent ver.
        /// <summary>
        /// Dots folder
        /// </summary>
        public const string DOTS_FOLDER = "dots";
        /// <summary>
        /// Color scheme folder name
        /// </summary>
        public const string COLOR_SCHMES_FOLDER = "color-schemes";

        /// <summary>
        /// Contains a cache of dot images
        /// </summary>
        private static Dictionary<string, Bitmap> dotsList;

        /// <summary>
        /// Contains a cache of color schemes
        /// </summary>
        private static Dictionary<string, Bitmap> colorSchemeList;

        private static GHeat _nonWebInstance = new GHeat();
        /// <summary>
        /// Used for locking to ensure multi thread capability
        /// </summary>
        private static Object _instanceLocker = new Object();

        /// <summary>
        /// Loads all of the color schemes and dots into the cache
        /// </summary>
        private GHeat()
        {
            string directory = @"C:\drop\Dropbox\Skóli\Söfnun gagna og framsetning\VisualTest\VisualTest\Content\__\etc\";
            dotsList = new Dictionary<string, Bitmap>();
            colorSchemeList = new Dictionary<string, Bitmap>();

            foreach (string file in System.IO.Directory.GetFiles(directory + DOTS_FOLDER, "*." + ImageFormat.Png.ToString().ToLower()))
                dotsList.Add(Path.GetFileName(file), new Bitmap(file));

            foreach (string file in System.IO.Directory.GetFiles(directory + COLOR_SCHMES_FOLDER, "*." + ImageFormat.Png.ToString().ToLower() ))
                colorSchemeList.Add(Path.GetFileName(file), new Bitmap(file));
        }

        /// <summary>
        /// Gets a single tile
        /// </summary>
        /// <param name="pm"></param>
        /// <param name="colorScheme"></param>
        /// <param name="zoom"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="newMethod">An attempt at a divide an conquer via threading. Turned out to be slower than just a row scan</param>
        /// <param name="changeOpacityWithZoom"></param>
        /// <param name="defaultOpacity"> Default opacity when changeOpacityWithZoom is false</param>
        /// <returns></returns>
        public static Bitmap GetTile(PointManager pm, string colorScheme, int zoom, int x, int y, bool newMethod, bool changeOpacityWithZoom, int defaultOpacity)
        {
            //Do a little error checking
            if (colorScheme == string.Empty) throw new Exception("A color scheme is required");
            if (pm == null) throw new Exception("No point manager has been specified");
            return Tile.Generate(GetColorScheme(colorScheme), GetDot(zoom), zoom, x, y, pm.GetPointsForTile(x, y, GetDot(zoom), zoom, newMethod), changeOpacityWithZoom,defaultOpacity);            
        }
        /// <summary>
        /// Gets a single tile
        /// Default method that matches the output of the python gheat
        /// </summary>
        /// <param name="pm"></param>
        /// <param name="colorScheme"></param>
        /// <param name="zoom"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static Bitmap GetTile(PointManager pm, string colorScheme, int zoom, int x, int y)
        {
            return GetTile(pm, colorScheme, zoom, x, y, false, true, 0);
        }

        /// <summary>
        /// Gets a dot from the cache
        /// </summary>
        /// <param name="zoom"></param>
        /// <returns></returns>
        private static Bitmap GetDot(int zoom)
        {
            return dotsList["dot" + zoom.ToString() + "." + ImageFormat.Png.ToString().ToLower()];
        }

        /// <summary>
        /// Gets the color scheme from the cache
        /// </summary>
        /// <param name="schemeName"></param>
        /// <returns></returns>
        public static Bitmap GetColorScheme(string schemeName)
        {
            if (!colorSchemeList.ContainsKey(schemeName + "." + ImageFormat.Png.ToString().ToLower()))
                throw new Exception("Color scheme '" + schemeName + " could not be found");
            return colorSchemeList[schemeName + "." + ImageFormat.Png.ToString().ToLower()];
        }

        public static string[] AvailableColorSchemes()
        {
            List<string> colorSchemes = new List<string>();

            //I dont want to return the file extention just the name
            foreach (string key in colorSchemeList.Keys)
                colorSchemes.Add(key.Replace("." + ImageFormat.Png.ToString().ToLower(), ""));
            return colorSchemes.ToArray(); 
        }
    }
}
